﻿using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Repository;
using DFGK_WMS.WebAPI.AttributeFile;
using DFGK_WMS.WebAPI.Controllers.Result;
using DFGK_WMS.WebAPI.Tools;
using Dm.Config;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.Functions;
using NPOI.XWPF.UserModel;
using System.Collections;
using System.Collections.Generic;
using System.Net.Mime;
using System.Security.Claims;

namespace DFGK_WMS.WebAPI.Controllers.出库管理
{
    /// <summary>
    /// 出库
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class TShippingOrderDetailController : ControllerBase
    {
        private readonly ILogRepository logRepository;
        private readonly ITOutboundOrderDetailRepository tOutbound;
        private readonly ITInventoryRepository tInventory;
        private readonly ITShippingLockCellRepository tShippingLockCell;
        private readonly ITWarehouseRepository tWarehouse;
        private readonly IAreaRepository area;

        public ITShippingOrderDetailRepository _service { get; set; }

        public TShippingOrderDetailController(
            ITShippingOrderDetailRepository service,
            ITInventoryRepository tInventory,
            ITShippingLockCellRepository tShippingLockCell,
            ITWarehouseRepository tWarehouse,
            IAreaRepository area,
            ILogRepository logRepository,
            ITOutboundOrderDetailRepository tOutbound
            )
        {
            _service = service;
            this.logRepository = logRepository;
            this.tOutbound = tOutbound;
            this.tInventory = tInventory;
            this.tShippingLockCell = tShippingLockCell;
            this.tWarehouse = tWarehouse;
            this.area = area;
        }


        /// <summary>
        /// 删除出库单
        /// </summary>
        /// <param name="OrderSn"></param>
        /// <returns></returns>
        [HttpDelete("DeleteTShippingOrderDetail")]
        public IActionResult DeleteTShippingOrderDetail(string OrderSn)
        {
            if (OrderSn == null)
            {
                return Ok(BaseResult.Result("400", "请求参数有误！"));
            }
            bool IsOK = _service.DeleteTShippingOrderDetail(OrderSn, out string errorMsg);
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            TLog logg = new TLog
            {
                LogType = 1,
                ActionType = 5,
                ModuleName = "出库管理",
                UserName = uname,
                RealName = runame,
                UserId = uid,
                Description = IsOK ? uname + "删除了出库单，单号：" + OrderSn : uname + "删除出库单失败：" + errorMsg + "，单号：" + OrderSn,
                Ipaddress = ip,
                Status = IsOK ? 1 : 0
            };
            logRepository.AddTLod(logg);
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "删除成功！", "200"));
            }
            return Ok(BaseResult.Result(false, errorMsg, "500"));
        }
        /// <summary>
        /// 批量删除出库单
        /// </summary>
        /// <param name="OrderSnList"></param>
        /// <returns></returns>
        [HttpDelete("DeleteTShippingOrderDetailList")]
        public IActionResult DeleteTShippingOrderDetailList(string[] OrderSnList)
        {
            if (OrderSnList.Count() <= 0)
            {
                return Ok(BaseResult.Result("400", "请求参数有误！"));
            }
            var deleteModel = _service.GetAll().Where(x => OrderSnList.Contains(x.OrderSn));
            if (deleteModel.Any(s => s.Status != 0))
            {
                return Ok(BaseResult.Result(false, "只有创建状态的出库单才可被删除", "500"));
            }
            bool IsOK = true;
            string errorMsg = string.Empty;
            foreach (var OrderSn in OrderSnList)
            {
                var isOk = _service.DeleteTShippingOrderDetail(OrderSn, out errorMsg);
                string uname = HttpContext.User.FindFirstValue("UserName");
                string runame = HttpContext.User.FindFirstValue("RealName");
                int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TLog logg = new TLog
                {
                    LogType = 1,
                    ActionType = 5,
                    ModuleName = "出库管理",
                    UserName = uname,
                    RealName = runame,
                    UserId = uid,
                    Description = isOk ? uname + "删除了出库单，单号：" + OrderSn : uname + "删除出库单失败：" + errorMsg,
                    Ipaddress = ip,
                    Status = isOk ? 1 : 0
                };
                logRepository.AddTLod(logg);
                if (!isOk)
                {
                    IsOK = false;
                    break;
                }
            }
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "删除成功！", "200"));
            }
            return Ok(BaseResult.Result(false, errorMsg, "500"));
        }

        /// <summary>
        /// 修改出库表 多个物料版本
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPut("UpdateTShippingOrderDetailPlus")]
        public IActionResult UpdateTShippingOrderDetailPlus(TShippingOrderDetailPlusDTO model)
        {
            var update = _service.UpdateTshippingOrderDetailPlus(model, out var errorMsg);
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            TLog logg = new TLog
            {
                LogType = 1,
                ActionType = 6,
                ModuleName = "出库管理",
                UserName = uname,
                RealName = runame,
                UserId = uid,
                Description = update ? uname + "修改了出库单，单号：" + model.OrderSn : uname + "修改出库单失败：" + errorMsg + ",单号：" + model.OrderSn,
                Ipaddress = ip,
                Status = update ? 1 : 0
            };
            logRepository.AddTLod(logg);
            if (update)
                return Ok(BaseResult.Result(true, "修改成功", "200"));
            return Ok(BaseResult.Result(false, errorMsg, "500"));
        }

        /// <summary>
        /// 显示出库表
        /// </summary>
        /// <param name="shelvesNo"></param>
        /// <param name="material"></param>
        /// <param name="status"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("GetPickDetailsList")]
        public IActionResult GetPickDetailsList(string? shelvesNo, string? material, int? status, int pageIndex, int pageSize)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            int totalCount;

            var list = _service.GetPickDetailsList(shelvesNo, material, status, pageIndex, pageSize, out totalCount);
            if (list.Count >= 0)
            {
                return Ok(BaseResult.Result(list, "查询成功！", "200", totalCount));
            }
            return Ok(BaseResult.Result(null, "查询失败！", "500", 0));
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <returns></returns>
        [HttpGet("ExportToExcel")]
        public FileContentResult ExportToExcel(DateTime? startTime, DateTime? endTime, int? billType, int? houseid, string? name)
        {
            var list = _service.GetOuHouseToExcel(startTime, endTime, billType, houseid, name, 1, int.MaxValue, out var totalCount);
            var dic = new Dictionary<string, string>()
            {
                {"OrdeSn","单号" },
                {"MaterialName","物料描述" },
                {"MaterialCode","物料代码" },
                {"isChuku", "状态"},
                {"BatchNo","批次" },
                {"SmallBatchNo","详细批次" },
                {"CellName","仓位名称" },
                {"OutQty","出库数量" },
                {"InvCount","库存剩余数量" },
                {"keChuCount","可出库数量" },
                {"PalletBarcode","托盘条码" },
                {"ProductionTime","生产时间" },
                {"CarCode","车牌号" }
            };
            var exList = list.Select(s => new
            {
                s.OrdeSn,
                s.MaterialName,
                s.MaterialCode,
                isChuku = s.IsPicking.GetValueOrDefault() ? "已出库" : "未出库",
                s.BatchNo,
                s.SmallBatchNo,
                s.CellName,
                s.CarCode,
                InvCount = (int)s.InvCount.GetValueOrDefault(),
                OutQty = (int)s.OutQty.GetValueOrDefault(),
                keChuCount = (int)s.keChuCount.GetValueOrDefault(),
                s.PalletBarcode,
                s.ProductionTime
            }).ToList();
            var fileBytes = Utils.ExportToExcel(exList, dic);
            return File(fileBytes, MediaTypeNames.Application.Octet, "出库管理.xlsx");
        }

        /// <summary>
        /// 修改状态
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPut("UpdTShippingOrderDetailState")]
        public IActionResult UpdTShippingOrderDetailState(ReceivingOrderDetailDto m)
        {
            bool IsOK = _service.UpdTShippingOrderDetailState(m);
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "修改成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "修改失败！输入的工号有误！", "500"));
        }

        /// <summary>
        /// 根据物料Id返回批次和数量(之前)
        /// 现：根据选择的物料返回可选择的批次号下拉框
        /// </summary>
        /// <param name="materialId"></param>
        /// <param name="batchNO"></param>
        /// <param name="qualityState"></param>
        /// <param name="whCode"></param>
        /// <param name="areaCode"></param>
        /// <param name="produceFactory"></param>
        /// <param name="ownerId"></param>
        /// <param name="supplierId"></param>
        /// <returns></returns>
        [HttpGet("GetMaterialIdById")]
        public IActionResult GetMaterialIdById(int materialId, string? batchNO, int? qualityState, string? whCode, string? areaCode, string? produceFactory, int? ownerId, int? supplierId = null)
        {
            if (materialId <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            var mobj = _service.GetMaterialIdById(materialId, batchNO, qualityState, whCode, areaCode, ownerId, supplierId, produceFactory);
            if (mobj != null)
            {
                return Ok(BaseResult.Result(mobj, "获取成功", "200"));
            }
            return Ok(BaseResult.Result(null, "获取失败！", "500"));
        }
        ///// <summary>
        ///// 一键选定 弃用
        ///// </summary>
        ///// <param name="materid"></param>
        ///// <param name="count"></param>
        ///// <param name="whid"></param>
        ///// <param name="areaid"></param>
        ///// <param name="supid"></param>
        ///// <param name="owid"></param>
        ///// <returns></returns>
        //[HttpGet("GetAllTShippingLockCell")]
        //public IActionResult GetAllTShippingLockCell(string? batchNO, int MaterialId, decimal Qty, string whCode, int? qualityState, string? areaCode, int? SupplierId, int? OwnerId, int? orderDetailId = null, string? produceFactory = "")
        //{


        //    //_service.GetAllTShippingLockCell(materid, count, whid, areaid, supid, owid);
        //    var res = tShippingLockCell.LockCell(whCode, areaCode, MaterialId, batchNO, qualityState, Qty, OwnerId, out var lockCellList, out var errorMsg, orderDetailId, SupplierId, produceFactory);
        //    if (res)
        //        return Ok(BaseResult.Result(lockCellList, "查询成功！", "200"));
        //    return Ok(BaseResult.Result(false, errorMsg, "500"));
        //}

        /// <summary>
        /// 获取货品明细
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("GetOneTShippingGoods")]
        public IActionResult GetOneTShippingGoods(int id, int pageIndex = 1, int pageSize = 8)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            int totalCount;
            var goodsDetail = _service.GetOneTShippingGoodsDetail(id, pageIndex, pageSize, out totalCount);
            if (goodsDetail != null)
            {
                return Ok(BaseResult.Result(goodsDetail, "查询成功！", "200", totalCount));
            }
            return Ok(BaseResult.Result(null, "查询失败！", "500", 0));
        }

        /// <summary>
        /// 根据名字获取
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("GetByNameShippingGoodsDetail")]
        public IActionResult GetByNameShippingGoodsDetail(string? name, int pageIndex = 1, int pageSize = 8)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            int totalCount;
            var goodsDetail = _service.GetByNameShippingGoodsDetail(name, pageIndex, pageSize, out totalCount);
            if (goodsDetail != null && goodsDetail.Any())
            {
                return Ok(BaseResult.Result(goodsDetail, "查询成功！", "200", totalCount));
            }
            return Ok(BaseResult.Result(null, "查询失败！", "500", 0));
        }

        /// <summary>
        /// 根据单号查询明细
        /// </summary>
        /// <param name="OrderSn"></param>
        /// <returns></returns>
        [HttpGet("GetOneTShippingOrderDetailPlus")]
        public IActionResult GetOneTShippingOrderDetailPlus(string OrderSn)
        {
            if (OrderSn == null)
            {
                return Ok(BaseResult.Result("500", "请求参数有误！"));
            }
            var list = _service.GetOneTShippingOrderDetailPlus(OrderSn);
            if (list == null)
            {
                return Ok(BaseResult.Result(null, "查询失败！", "500"));
            }
            return Ok(BaseResult.Result(list, "查询成功！", "200"));
        }

        /// <summary>
        /// 出库任务下传
        /// </summary>
        /// <param name="shipping"></param>
        /// <returns></returns>
        [HttpPost("ShippingTaskDownload")]
        public IActionResult ShippingTaskDownload(ShippingDowload shipping)
        {
            string message = "";
            if (shipping.PickDetails.Count <= 0)
            {
                return Ok(BaseResult.Result("400", "入参不能为空！"));
            }
            bool IsOK = _service.ShippingTaskDownload(shipping.PickDetails, out message);
            if (IsOK)
            {
                string uname = HttpContext.User.FindFirstValue("UserName");
                string runame = HttpContext.User.FindFirstValue("RealName");
                int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TLog logg = new TLog();
                logg.LogType = 1;
                logg.ActionType = 4;
                logg.ModuleName = "出库管理";
                logg.UserName = uname;
                logg.RealName = runame;
                logg.UserId = uid;
                //logg.Description = uname + "创建了收货单" + m.BillNo;
                //获取前端IP地址
                logg.Ipaddress = ip;

                logRepository.AddTLod(logg);
                return Ok(BaseResult.Result(true, "添加成功！" + message, "200"));
            }
            return Ok(BaseResult.Result(false, "添加失败！" + message, "500"));
        }

        /// <summary>
        /// 出库单回传
        /// </summary>
        /// <returns></returns>
        [HttpGet("BackShippingOrder")]
        public IActionResult BackShippingOrder()
        {
            var list = _service.BackShippingOrder();
            if (list != null)
            {
                return Ok(BaseResult.Result(list, "获取成功！", "200", 0));
            }
            return Ok(BaseResult.Result(list, "获取失败！", "500", 0));
        }

        /// <summary>
        /// 获取出库物料
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="mname"></param>
        /// <returns></returns>
        [HttpGet("GetInventoryByMaterialAll")]
        public IActionResult GetInventoryByMaterialAll(int pageIndex, int pageSize, string? mname)
        {
            int count = 0;
            var list = _service.GetInventoryByMaterialAll(pageIndex, pageSize, mname, out count);
            if (list == null)
            {
                return Ok(BaseResult.Result(null, "查询失败！", "500", 0));
            }
            return Ok(BaseResult.Result(list, "查询成功！", "200", count));
        }

        /// <summary>
        /// 出库回传成功修改状态
        /// </summary>
        /// <param name="ridlist"></param>
        /// <returns></returns>
        [HttpPost("UpdBackShippingState")]
        public IActionResult UpdBackShippingState(List<string> ridlist)
        {
            if (!ridlist.Any())
            {
                return Ok(BaseResult.Result("400", "请求参数有误！"));
            }
            var robj = _service.UpdBackShippingState(ridlist);
            if (robj)
            {
                return Ok(BaseResult.Result(true, "修改成功！", "200"));
            }
            return Ok(BaseResult.Result(true, "修改失败！", "500"));
        }

        /// <summary>
        /// 添加出库单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost("AddTShippingOrderDetail")]
        public IActionResult AddTShippingOrderDetail(TShippingOrderDetail model)
        {
            var create = _service.AddTShippingOrderDetail(model, out string msg);
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            model.CreateUserName = uname;//创建人
            model.CreateUserId = uid;//创建人id
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            if (create)
            {
                TLog logg = new TLog
                {
                    LogType = 1,
                    ActionType = 4,
                    ModuleName = "出库管理",
                    UserName = uname,
                    RealName = runame,
                    UserId = uid,
                    Description = create ? uname + "创建了出库单，单号：" + model.OrderSn : uname + "创建出库单失败：" + msg + ",单号：" + model.OrderSn,
                    Ipaddress = ip,
                    Status = create ? 1 : 0
                };
                logRepository.AddTLod(logg);
            }
            if (create)
            {
                return Ok(BaseResult.Result(true, "添加成功", "200"));
            }
            return Ok(BaseResult.Result(false, msg, "500"));
        }
    }
}